/**
 * 第五课 函数
 */
class Demo5 {
    name: string;
    // 构造函数(匿名函数)
    constructor() {
        console.log('函数测试');
    }
    // 函数接受2个number类型参数 返回类型为number
    // 该函数接受的参数为2个，当该参数没有设置为可选参数或参数没有给定默认值时，在调用该参数时务必传递对应的参数个数
    // 可选参数以?问号标识
    add(x: number, y?: number): number {
        return x + y;
    }
    // 方法的重载,根据参数类型来分别加载不同的方法。
    reload(x: number[]): number;
    reload(x: string): string;
    reload(x): any {
        if (typeof x === 'object') {
            return Math.max.apply(null, x);
        } else {
            return `string is ${x}`;
        }
    }
    // 注意，可选参数务必是函数参数中的最后一个
    // 在函数参数中若存在默认值时，后续参数又不是可选时，在调用该函数时若需要使用参数默认值，需传递参数为undefined。如：join('a',undefined,'c') //abc
    // 注意，在有默认值并且需要使用默认值得时候，我们务必需要传递值为undefined，内部将使用===来判断传递的值，null!==undefined
    joinStr(a: string, b: string = 'b', c: string, d?: string) {
        return a + b + c + d;
    }
    // 这里我们使用了参数默认值，可选参数，剩余参数
    // 剩余参数务必放在所有参数的最后，传递值时将以此对应，剩余的传递参数将以数组的形式收集。
    sayHello(name = '张三', age: number = 34, habby?: string, ...other) {
        Array.isArray(other) // true
        return `my name is ${name} I'm ${age} year's old my like ${habby} and ` + other.join(',');
    }
    // 参数中给定默认值
    setName(name: string = 'zhangsan') {
        this.name = name;
    }
    getName() {
        return this.name;
    }
}

let d5 = new Demo5();
// 若給add函数传递的参数数目不对且add的参数没有默认值时，编译不通过，提示缺少参数
console.log(d5.add(1));// NaN 此时y的值没有传递，在add函数中y的值将为undefined，故return NaN
console.log(d5.joinStr('a', undefined, 'c')); // abcundefined
console.log(d5.sayHello(undefined, 23, 'game', 'play', 'whatch')); //"my name is 张三 I'm 23 year's old my like game and play,whatch"
//重载
console.log(d5.reload([54, 2, 3, 55, 32])); // 55
console.log(d5.reload('abc')); // string is abc

d5.setName('jack')
console.log(d5.getName()); //jack
d5.setName();
console.log(d5.getName()); //zhangsan
let obj = {
    name: 'obj',
    sayName: function () {
        return function () {
            return this.name;
        }
    },
    sayHi: function () {
        return () => {
            return this.name;
        }
    }
}
console.log(obj.sayName()()); //undefined 此时this指向为window
console.log(obj.sayHi()()); // obj 使用箭头函数，this指向obj


interface Card {
    name: string
}
interface Dack {
    name: string,
    age: number;
    // 规定this类型
    other(this: Dack): () => Card;
}
let dack = {
    name: '张三',
    age: 22,
    other: function (this: Dack) {
        return () => {
            return { name: this.name };
        }
    }
}
// 调用dack对象中的other方法
console.log(dack.other()()); //{ name: '张三' }



